/**
 * @author Sekkina
 */

package controllers;

import java.util.ArrayList;
import java.util.List;

import play.mvc.Controller;
import play.mvc.With;
import play.test.Fixtures;

import com.google.gson.JsonObject;

import models.ActionPlan;
import models.Entities;
import models.Idea;
import models.IdeaDeveloper;
import models.Organization;
import models.OrganizationLead;
import models.Organizer;
import models.Tag;
import models.Topic;

@With(Secure.class)
public class BrowseController extends Controller {
	
	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page userView.html
	 */
	public static void userView() {
		String user = Security.connected();
		render(user);
	}
	
	public static void TagView(String tagToRenderName) {
		String userName = Security.connected();
		String tagName = tagToRenderName;
		render(userName, tagName);
	}

	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page BrowseOrganizations.html
	 */
	public static void BrowseOrganizations() {
		String user = Security.connected();
		render(user);
	}

	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page BrowseEntities.html
	 */
	public static void BrowseEntities() {
		String user = Security.connected();
		render(user);
	}

	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page BrowseTopics.html
	 */
	public static void BrowseTopics() {
		String user = Security.connected();
		render(user);
	}

	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page BrowseIdeaPage.html
	 */
	public static void BrowseIdeasPage() {
		String user = Security.connected();
		render(user);
	}

	/**
	 * Renders the user name of the user logged in
	 * @see
	 * Loads the page Browse.html
	 */
	public static void Browse() {
		String user = Security.connected();
		render(user);
	}

	// -------------------------------------------------------------------------------------------------------------------
	// Browse Organizations
	// --------------------------------------------------------------------------------------------------------------------
	/**
	 * A method that returns back a list of the organizations joined by this
	 * user
	 * 
	 * @param userName
	 *            The user name of the user which is unique
	 * @return ArrayList of organizations followed by the user
	 */
	public static List browseJoinedOrganizationsHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Organization> myOrganizations = user.joinedOrg;
			for(int i=0; i<myOrganizations.size(); i++){
				if(!IdeaDeveloper.canViewOrganization(user, myOrganizations.get(i))){
					myOrganizations.remove(i);
				}
			}
			return myOrganizations;
		}
	}

	/**
	 * Returns back a list of the organizations followed by this
	 * user
	 * 
	 * @param userName
	 *            The user name of the user which is unique
	 * @return ArrayList of organizations followed by the user
	 */
	public static List browseFollowedOrganizationsHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Organization> myOrganizations = user.followedOrg;
			for(int i=0; i<myOrganizations.size(); i++){
				if(!IdeaDeveloper.canViewOrganization(user, myOrganizations.get(i))){
					myOrganizations.remove(i);
				}
			}
			return myOrganizations;
		}
	}

	/**
	 * Returns a list of all organizations managed by an
	 * oganizationLead
	 * 
	 * @param userName String
	 *            The user name of the organization lead
	 * @return ArrayList of organizations which the user manages
	 */
	public static List browseManagedOrganizationsHelper(String userName) {
		IdeaDeveloper iD = (IdeaDeveloper) IdeaDeveloper.find("username = ?",
				userName).first();
		List temp = OrganizationLead.find("ideaDeveloper = ?", iD).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			OrganizationLead user = (OrganizationLead) temp.get(0);
			List<Organization> myOrganizations = user.manages;
			for(int i=0; i<myOrganizations.size(); i++){
				if(!IdeaDeveloper.canViewOrganization(iD, myOrganizations.get(i))){
					myOrganizations.remove(i);
				}
			}
			return myOrganizations;
		}
	}

	/**
	 * Renders a json object with a string of names of joined
	 * organizations
	 * 
	 * @param userName
	 *            String the user name of the user applying the action
	 */
	public static void browseOrganizationsJoined(String userName) {
		List<Organization> myJoinedOrganizations = browseJoinedOrganizationsHelper(userName);
		String orgNamesJoined = "";
		if (myJoinedOrganizations != null) {
			for (int i = 0; i < myJoinedOrganizations.size(); i++) {
				orgNamesJoined += myJoinedOrganizations.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("joinedOrgs", orgNamesJoined);
		renderJSON(json.toString());
	}

	/**
	 * Renders a json object with a string of names of followed
	 * organizations
	 * 
	 * @param userName
	 *            String the user name of the user applying the action
	 */
	public static void browseOrganizationsFollowed(String userName) {
		List<Organization> myFollowedOrganizations = browseFollowedOrganizationsHelper(userName);
		String orgNamesFollowed = "";
		if (myFollowedOrganizations != null) {
			for (int i = 0; i < myFollowedOrganizations.size(); i++) {
				orgNamesFollowed += myFollowedOrganizations.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("followedOrgs", orgNamesFollowed);
		renderJSON(json.toString());
	}

	/**
	 * Renders a json object with a string of names of managed
	 * organizations
	 * 
	 * @param userName
	 *            String the user name of the user applying the action
	 */
	public static void browseOrganizationsManaged(String userName) {
		JsonObject json = new JsonObject();
		List<Organization> myManagedOrganizations = browseManagedOrganizationsHelper(userName);
		IdeaDeveloper iD = IdeaDeveloper.find("username", userName).first();
		List temp = OrganizationLead.find("ideaDeveloper.id = ?", iD.id)
				.fetch();
		String orgNamesManaged = "";
		if (myManagedOrganizations != null) {
			for (int i = 0; i < myManagedOrganizations.size(); i++) {
				orgNamesManaged += myManagedOrganizations.get(i).name + "&&";
			}
		}

		json.addProperty("managedOrgs", orgNamesManaged);
		renderJSON(json.toString());
	}

	/**
	 * takes user and organization and returns entities inside it that a user
	 * can view
	 * 
	 * @param org
	 *            the organization that the user wants to view
	 * @param user
	 *            the user who wants to see the entities inside the organization
	 * @return returns a list of entities that can be viewed by a user inside
	 *         this organization
	 */

	public static List viewEntitiesInsideOrg(Organization org,
			IdeaDeveloper user) {
		List<Entities> entities = org.liesIn;
		if (entities != null) {
			for (int i = 0; i < entities.size(); i++) {
				if (!IdeaDeveloper.canViewEntity(user, entities.get(i))) {
					entities.remove(i);
				}
			}
		}
		return entities;
	}

	/**
	 * takes user and organization and returns topics inside it that a user can
	 * view
	 * 
	 * @param org
	 *            the organization that the user wants to view
	 * @param user
	 *            the user who wants to see the topics inside the organization
	 * @return returns a list of topics in the organization that a user can view
	 */

	public static List viewTopicsInsideOrg(Organization org, IdeaDeveloper user) {
		List<Topic> topics = org.topics;
		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				if (!IdeaDeveloper.canViewTopic(user, topics.get(i))) {
					topics.remove(i);
				}
			}
		}
		return topics;
	}

	/**
	 * It get back a list of ideas that a user can see inside an organization
	 * 
	 * @param org
	 *            The organization
	 * @param user
	 *            The user that wants to perform that action
	 * @return A List of ideas that a user can see
	 */

	public static List viewIdeasInsideOrg(Organization org, IdeaDeveloper user) {
		List<Idea> ideas = org.ideas;
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				if (!user.canViewIdea(user, ideas.get(i))) {
					ideas.remove(i);
				}
			}
		}
		return ideas;
	}

	/**
	 * @author Sekkina 
	 * Renders a JSON object which has two lists, one of the
	 * entities names and one of the topics names inside the
	 *         organization
	 * @param orgName
	 *            The name of the organization the user wants to browse inside
	 * @param userName
	 *            The name of the user wants to browse the organization
	 */
	public static void showOrgContents(String orgName, String userName) {
		JsonObject json = new JsonObject();
		List temp = Organization.find("name=?", orgName).fetch();
		Organization org = new Organization();
		if (temp != null && temp.size() > 0)
			org = (Organization) temp.get(0);
		List temp2 = IdeaDeveloper.find("username=?", userName).fetch();
		IdeaDeveloper user = new IdeaDeveloper();
		if (temp2 != null && temp2.size() > 0)
			user = (IdeaDeveloper) temp2.get(0);
		List<Idea> ideas = viewIdeasInsideOrg(org, user);
		List<Topic> topics = viewTopicsInsideOrg(org, user);
		List<Entities> entities = viewEntitiesInsideOrg(org, user);
		String ideasNames = "";
		String topicsNames = "";
		String entitiesNames = "";
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				ideasNames += ideas.get(i).id + "-" + ideas.get(i).title + "&&";
			}
		}

		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				topicsNames += topics.get(i).id + "-" + topics.get(i).title
						+ "&&";
			}
		}

		if (entities != null) {
			for (int i = 0; i < entities.size(); i++) {
				entitiesNames += entities.get(i).name + "&&";
			}
		}

		json.addProperty("entities", entitiesNames);
		json.addProperty("topics", topicsNames);
		json.addProperty("ideas", ideasNames);
		renderJSON(json.toString());
	}

	/**
	 * Renders the organizations starting with a character, the organization a user is allowed to view
	 * @param startingLetter
	 *            String, The letter that a user wants to see the organizations
	 *            starting with
	 * @param userName
	 *            String, The user name of the user currently logged in to the
	 *            system and browsing
	 * @see Renders a string with all the organizations that a user with
	 *      username userName and starting with the letter startingLetter to the
	 *      page BrowseAll.html
	 */
	public static void browseOrganizationsByCharacter(String startingLetter,
			String userName) {
		JsonObject renderedOrganizations = new JsonObject();
		String renderedOrgsNames = "";
		IdeaDeveloper user = new IdeaDeveloper();
		List temp = IdeaDeveloper.find("username = ?", userName).fetch();
		if (temp != null && temp.size() > 0)
			user = (IdeaDeveloper) temp.get(0);
		else {
			renderedOrganizations.addProperty("orgs", renderedOrgsNames);
			renderJSON(renderedOrganizations.toString());
			return;
		}
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<Organization> orgs = Organization.find(
				"name like ? or name like ? order by name asc",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();

		if (orgs != null) {
			for (int i = 0; i < orgs.size(); i++) {
				if (IdeaDeveloper.canViewOrganization(user, orgs.get(i))) {
					renderedOrgsNames += orgs.get(i).name + "&&";
				}
			}
		}

		renderedOrganizations.addProperty("orgs", renderedOrgsNames);
		renderJSON(renderedOrganizations.toString());
	}

	// --------------------------------------------------------------------------------------------------------------------
	// Browse entities
	// --------------------------------------------------------------------------------------------------------------------

	/**
	 * A method that returns back a list of entities followed by a user
	 * 
	 * @param userName String,
	 *            The user name of the user
	 * @return ArrayList of followed entities
	 */
	public static List browseJoinedEntitiesHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Entities> myEntities = user.joinedEnt;
			for(int i=0; i<myEntities.size(); i++){
				if(!IdeaDeveloper.canViewEntity(user, myEntities.get(i))){
					myEntities.remove(i);
				}
			}
			return myEntities;
		}
	}

	/**
	 * A method that returns back a list of entities followed by a user
	 * 
	 * @param userName String,
	 *            The user name of the user applying the action
	 * @return ArrayList of followed entities
	 */
	public static List browseFollowedEntitiesHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Entities> myEntities = user.followedEnt;
			for(int i=0; i<myEntities.size(); i++){
				if(!IdeaDeveloper.canViewEntity(user, myEntities.get(i))){
					myEntities.remove(i);
				}
			}
			return myEntities;
		}
	}

	/**
	 * Returns back a list of entities managed by a user
	 * 
	 * @param userName String,
	 *            The user name of the user
	 * @return ArrayList of entities managed by the user
	 */
	public static List browseManagedEntitiesHelper(String userName) {
		IdeaDeveloper iD = IdeaDeveloper.find("username", userName).first();
		List temp = Organizer.find("ideaDeveloper=?", iD).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			Organizer user = (Organizer) temp.get(0);
			List<Entities> myEntities = user.manages;
			for(int i=0; i<myEntities.size(); i++){
				if(!IdeaDeveloper.canViewEntity(iD, myEntities.get(i))){
					myEntities.remove(i);
				}
			}
			return myEntities;
		}
	}

	/**
	 * Renders a json object with string of names of joined entities
	 * 
	 * @param userName String,
	 * 				The user name of the user doing the action
	 */
	public static void browseJoinedEntities(String userName) {
		List<Entities> myJoinedEntities = browseJoinedEntitiesHelper(userName);
		String entitNamesJoined = "";

		if (myJoinedEntities != null) {
			for (int i = 0; i < myJoinedEntities.size(); i++) {
				entitNamesJoined += myJoinedEntities.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("joinedEntits", entitNamesJoined);
		renderJSON(json.toString());
	}

	/**
	 * Renders a json object with string of names of followed entities
	 * 
	 * @param userName String, 
	 * The user name of the user doing the action
	 */
	public static void browseFollowedEntities(String userName) {
		List<Entities> myFollowedEntities = browseFollowedEntitiesHelper(userName);
		String entitNamesFollowed = "";
		if (myFollowedEntities != null) {
			for (int i = 0; i < myFollowedEntities.size(); i++) {
				entitNamesFollowed += myFollowedEntities.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("followedEntits", entitNamesFollowed);
		renderJSON(json.toString());
	}

	/**
	 * Renders a json object with string of names of joined entities
	 * 
	 * @param userName String,
	 * The user name of the user doing the action
	 */
	public static void browseManagedEntities(String userName) {
		List<Entities> myManagedEntities = browseManagedEntitiesHelper(userName);
		String entitNamesManaged = "";
		if (myManagedEntities != null) {
			for (int i = 0; i < myManagedEntities.size(); i++) {
				entitNamesManaged += myManagedEntities.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		IdeaDeveloper iD = IdeaDeveloper.find("username", userName).first();
		List temp = Organizer.find("ideaDeveloper=?", iD).fetch();
		json.addProperty("managedEntits", entitNamesManaged);
		renderJSON(json.toString());
	}

	/**
	 * takes user and entity and returns topics inside it that a user can view
	 * 
	 * @param ent Entities,
	 *            the entity that the user wants to view
	 * @param user IdeaDeveloper
	 *            the user who wants to see the topics inside the entity
	 * @return returns a list of topics that can be viewed by the user inside
	 *         this entity
	 */

	public static List viewTopicsInsideEntit(Entities ent, IdeaDeveloper user) {
		List<Topic> topics = ent.topics;
		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				if (!IdeaDeveloper.canViewTopic(user, topics.get(i))) {
					topics.remove(i);
				}
			}
		}
		return topics;
	}

	/**
	 * takes user and entity and returns entities inside it that a user can view
	 * 
	 * @param ent Entities
	 *            the entity that the user wants to view
	 * @param user IdeaDeveloper
	 *            the user who wants to see the entities inside the entity
	 * @return returns a list of entities that can be viewed by the user inside
	 *         this entity
	 */

	public static List viewEntitiesInsideEntit(Entities ent, IdeaDeveloper user) {
		List<Entities> entities = ent.childern;
		if (entities != null) {
			for (int i = 0; i < entities.size(); i++) {
				if (!IdeaDeveloper.canViewEntity(user, entities.get(i))) {
					entities.remove(i);
				}
			}
		}
		return entities;
	}

	/**
	 * takes user and entity and returns ideas inside it that a user can view
	 * 
	 * @param ent Entities
	 *            the entity that the user wants to view
	 * @param user IdeaDeveloper
	 *            the user who wants to see the entities inside the entity
	 * @return returns a list of ideas that can be viewed by the user inside
	 *         this entity
	 */
	public static List viewIdeasInsideEntit(Entities ent, IdeaDeveloper user) {
		List<Idea> ideas = ent.ideas;
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				if (!IdeaDeveloper.canViewIdea(user, ideas.get(i))) {
					ideas.remove(i);
				}
			}
		}
		return ideas;
	}

	/**
	 * A method that renders a Json object with two stings of
	 * 
	 * @author Sekkina entities and topics inside an entity
	 * @param entityName
	 *            String the name of the entity
	 * @param userName
	 *            String the user name of the user
	 */
	public static void showEntitContents(String entityName, String userName) {
		List temp = Entities.find("name=?", entityName).fetch();
		Entities entity = new Entities();
		if (temp != null && temp.size() > 0)
			entity = (Entities) temp.get(0);
		List temp2 = IdeaDeveloper.find("username=?", userName).fetch();
		IdeaDeveloper user = new IdeaDeveloper();
		if (temp2 != null && temp2.size() > 0)
			user = (IdeaDeveloper) temp2.get(0);
		List<Topic> topics = viewTopicsInsideEntit(entity, user);
		List<Entities> entities = viewEntitiesInsideEntit(entity, user);
		String topicsNames = "";
		String entitiesNames = "";
		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				topicsNames += topics.get(i).id + "-" + topics.get(i).title
						+ "&&";
			}
		}

		if (entities != null) {
			for (int i = 0; i < entities.size(); i++) {
				entitiesNames += entities.get(i).name + "&&";
			}
		}

		JsonObject json = new JsonObject();
		json.addProperty("entities", entitiesNames);
		json.addProperty("topics", topicsNames);
		renderJSON(json.toString());
	}

	/**
	 * 
	 * @param startingLetter
	 *            String, The letter that a user wants to see the entities
	 *            starting with
	 * @param userName
	 *            String, The user name of the user currently logged in to the
	 *            system and browsing
	 * @see Renders a string with all the entities that a user with username
	 *      userName and starting with the letter startingLetter to the page
	 *      BrowseAll.html
	 */
	public static void browseEntitiesByCharacter(String startingLetter,
			String userName) {
		JsonObject renderedEntities = new JsonObject();
		String renderedEntitsNames = "";
		IdeaDeveloper user = new IdeaDeveloper();
		List temp = IdeaDeveloper.find("username = ?", userName).fetch();
		if (temp != null && temp.size() > 0)
			user = (IdeaDeveloper) temp.get(0);
		else {
			renderedEntities.addProperty("entits", renderedEntitsNames);
			renderJSON(renderedEntities.toString());
			return;
		}
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<Entities> entits = Entities.find(
				"name like ? or name like ? order by name asc",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();
		if (entits != null) {
			for (int i = 0; i < entits.size(); i++) {
				if (IdeaDeveloper.canViewEntity(user, entits.get(i))) {
					renderedEntitsNames += entits.get(i).name + "&&";
				}
			}
		}

		renderedEntities.addProperty("entits", renderedEntitsNames);
		renderJSON(renderedEntities.toString());
	}

	// ----------------------------------------------------------------------------------------------------------------------------------------
	// Topics
	// ----------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * A method that returns back the topics created by a user
	 * 
	 * @param userName String,
	 *            String user name
	 * @return ArrayList of topics created by a user
	 */
	public static List browseTopicsjoinedHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Topic> myTopics = user.joinedTop;
			for(int i=0; i<myTopics.size(); i++){
				if(!IdeaDeveloper.canViewTopic(user, myTopics.get(i))){
					myTopics.remove(i);
				}
			}
			return myTopics;
		}
	}

	/**
	 * A method that returns back a list of topics that a user follows
	 * 
	 * @param userName String,
	 *            The user name
	 * @return ArrayList of topics followed by a user
	 */
	public static List browseTopicsFollowedHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Topic> myTopics = user.followedTop;
			for(int i=0; i<myTopics.size(); i++){
				if(!IdeaDeveloper.canViewTopic(user, myTopics.get(i))){
					myTopics.remove(i);
				}
			}
			return myTopics;
		}
	}

	/**
	 * A method that returns back the topics created by a user
	 * 
	 * @param userName String,
	 *            String user name
	 * @return ArrayList of topics created by a user
	 */
	public static List browseTopicsCreatedHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Topic> myTopics = user.createdTopics;
			for(int i=0; i<myTopics.size(); i++){
				if(!IdeaDeveloper.canViewTopic(user, myTopics.get(i))){
					myTopics.remove(i);
				}
			}
			return myTopics;
		}
	}

	/**
	 * A method that returns back the topics created by a user
	 * 
	 * @param userName String,
	 *            String user name
	 * @return ArrayList of topics created by a user
	 */
	public static List browseTopicsManagedHelper(String userName) {
		IdeaDeveloper iD = IdeaDeveloper.find("username=?", userName).first();
		List temp = Organizer.find("ideaDeveloper=?", iD).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			Organizer user = (Organizer) temp.get(0);
			List<Topic> myTopics = user.managedTopics;
			return myTopics;
		}
	}

	/**
	 * @author Sekkina
	 * @param userName String,
	 *            The user name of the user
	 * @return Renders a json object with string of topics
	 *         followed by a user
	 */
	public static void browseFollowedTopics(String userName) {
		List<Topic> myFollowedTopics = browseTopicsFollowedHelper(userName);
		String topicsNamesFollowed = "";
		if (myFollowedTopics != null) {
			for (int i = 0; i < myFollowedTopics.size(); i++) {
				if(myFollowedTopics.get(i).published == true){
					topicsNamesFollowed += myFollowedTopics.get(i).id + "-"
					+ myFollowedTopics.get(i).title + "&&";	
				}
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("followedTopics", topicsNamesFollowed);
		renderJSON(json.toString());
	}

	/**
	 * @author Sekkina
	 * @param userName String,
	 *            The user name of the user
	 * @return Renders a json object with string of topics
	 *         created by a user
	 */
	public static void browseCreatedTopics(String userName) {
		List<Topic> myCreatedTopics = browseTopicsCreatedHelper(userName);
		String topicsNamesCreated = "";
		if (myCreatedTopics != null) {
			for (int i = 0; i < myCreatedTopics.size(); i++) {
				if(myCreatedTopics.get(i).published == true){
					topicsNamesCreated += myCreatedTopics.get(i).id + "-"
					+ myCreatedTopics.get(i).title + "&&";	
				}
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("createdTopics", topicsNamesCreated);
		renderJSON(json.toString());
	}

	/**
	 * @author Sekkina
	 * @param userName String,
	 *            The user name of the user
	 * @return Renders a json object with string of topics
	 *         managed by a user
	 */
	public static void browseManagedTopics(String userName) {
		List<Topic> myManagedTopics = browseTopicsManagedHelper(userName);
		String topicsNamesManaged = "";
		if (myManagedTopics != null) {
			for (int i = 0; i < myManagedTopics.size(); i++) {
				if(myManagedTopics.get(i).published == true){
					topicsNamesManaged += myManagedTopics.get(i).id + "-"
					+ myManagedTopics.get(i).title + "&&";	
				}
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("managedTopics", topicsNamesManaged);
		renderJSON(json.toString());
	}

	/**
	 * Gets back a list of ideas that a user can see inside a topic
	 * 
	 * @param topic Topic
	 *            The topic
	 * @param user IdeaDeveloper
	 *            The user that wants to perform that action
	 * @return A List of ideas that a user can see
	 */

	public static List viewIdeasInsideTopic(Topic topic, IdeaDeveloper user) {
		List<Idea> ideas = topic.ideas;
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				if (!user.canViewIdea(user, ideas.get(i))) {
					ideas.remove(i);
				}
			}
		}
		return ideas;
	}

	/**
	 * Gets the ideas inside the topic
	 * @author Sekkina
	 * @param topicId String
	 *            The id of the topic that a user wants to browse
	 * @param userName String
	 *            The username of the user
	 */
	public static void showTopicContents(String topicId, String userName) {
		long id = 0;
		try {
			id = Long.valueOf(topicId);
		} catch (Exception e) {

		}
		List temp = Topic.find("id=?", id).fetch();
		Topic topic = new Topic();
		if (temp != null && temp.size() > 0)
			topic = (Topic) temp.get(0);
		List temp2 = IdeaDeveloper.find("username=?", userName).fetch();
		IdeaDeveloper user = new IdeaDeveloper();
		if (temp2 != null && temp2.size() > 0)
			user = (IdeaDeveloper) temp2.get(0);
		List<Idea> ideas = viewIdeasInsideTopic(topic, user);
		String ideasNames = "";

		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				ideasNames += ideas.get(i).id + "-" + ideas.get(i).title + "&&";
			}
		}

		JsonObject json = new JsonObject();
		json.addProperty("ideas", ideasNames);
		renderJSON(json.toString());

	}

	/**
	 * 
	 * @param startingLetter
	 *            String, The letter that a user wants to see the topics
	 *            starting with
	 * @param userName
	 *            String, The user name of the user currently logged in to the
	 *            system and browsing
	 * @see Renders a string with all the topics that a user with username
	 *      userName and starting with the letter startingLetter to the page
	 *      BrowseAll.html
	 */
	public static void browseTopicsByCharacter(String startingLetter,
			String userName) {
		JsonObject renderedTopics = new JsonObject();
		String renderedTopicsNames = "";
		IdeaDeveloper user = new IdeaDeveloper();
		List temp = IdeaDeveloper.find("username = ?", userName).fetch();
		if (temp != null && temp.size() > 0)
			user = (IdeaDeveloper) temp.get(0);
		else {
			renderedTopics.addProperty("topics", renderedTopicsNames);
			renderJSON(renderedTopics.toString());
			return;
		}
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<Topic> topics = Topic.find(
				"title like ? or title like ? order by title ASC",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();
		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				if (IdeaDeveloper.canViewTopic(user, topics.get(i))) {
					renderedTopicsNames += topics.get(i).id + "-"
							+ topics.get(i).title + "&&";
				}
			}
		}

		renderedTopics.addProperty("topics", renderedTopicsNames);
		renderJSON(renderedTopics.toString());
	}

	// ----------------------------------------------------------------------------------------------------------------------------------------
	// Ideas
	// ----------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * Takes a username a returns all its created ideas
	 * 
	 * @param userName String
	 *            String username which is unique
	 * @return ArrayList of ideas created by the user
	 */
	public static List ideasCreatedHelper(String userName) {
		List temp = IdeaDeveloper.find("username=?", userName).fetch();
		if (temp.size() == 0) {
			return null;
		} else {
			IdeaDeveloper user = (IdeaDeveloper) temp.get(0);
			List<Idea> myIdeas = user.createdIdeas;
			for(int i=0; i<myIdeas.size(); i++){
				if(!IdeaDeveloper.canViewIdea(user, myIdeas.get(i))){
					myIdeas.remove(i);
				}
			}
			return myIdeas;
		}
	}

	/**
	 * Renders a json object with two strings of ids of created and shared ideas
	 * 
	 * @param userName
	 *            String user name
	 */
	public static void browseIdeas(String userName) {
		List<Idea> myCreatedIdeas = ideasCreatedHelper(userName);
		String ideasNamesCreated = "";
		if (myCreatedIdeas != null) {
			for (int i = 0; i < myCreatedIdeas.size(); i++) {
				if(myCreatedIdeas.get(i).published == true){
					ideasNamesCreated += myCreatedIdeas.get(i).id + "-"
					+ myCreatedIdeas.get(i).title + "&&";	
				}
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("createdIdeas", ideasNamesCreated);
		renderJSON(json.toString());
	}

	/**
	 * 
	 * @param startingLetter
	 *            String, The letter that a user wants to see the Ideas starting
	 *            with
	 * @param userName
	 *            String, The user name of the user currently logged in to the
	 *            system and browsing
	 * @see Renders a string with all the Ideas that a user with username
	 *      userName and starting with the letter startingLetter to the page
	 *      BrowseAll.html
	 */
	public static void browseIdeasByCharacter(String startingLetter,
			String userName) {
		JsonObject renderedIdeas = new JsonObject();
		String renderedIdeasNames = "";
		IdeaDeveloper user = new IdeaDeveloper();
		List temp = IdeaDeveloper.find("username = ?", userName).fetch();
		if (temp != null && temp.size() > 0)
			user = (IdeaDeveloper) temp.get(0);
		else {
			renderedIdeas.addProperty("ideas", renderedIdeasNames);
			renderJSON(renderedIdeas.toString());
			return;
		}
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<Idea> ideas = Idea.find(
				"title like ? or title like ? order by title asc",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				if (IdeaDeveloper.canViewIdea(user, ideas.get(i))) {
					renderedIdeasNames += ideas.get(i).id + "-"
							+ ideas.get(i).title + "&&";
				}
			}
		}

		renderedIdeas.addProperty("ideas", renderedIdeasNames);
		renderJSON(renderedIdeas.toString());
	}

	// ----------------------------------------------------------------------------------------------------------------------------------------
	// Browse Tags
	// ----------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * Gets back a list of tags with highest number of related items
	 * 
	 * @return Returns list of Tag
	 */

	public static List browseTagsHelper() {
		List mostViewedTags = Tag.find(
				"Select T from Tag T order by relatedItems DESC").fetch(5);
		return mostViewedTags;
	}

	/**
	 * Renders a string containing the tags that a user can browse
	 * 
	 * @see Renders a string of names of most viewed tags
	 */
	public static void browseTags() {
		List<Tag> tags = browseTagsHelper();
		String tagsNames = "";
		if (tags != null) {
			for (int i = 0; i < tags.size(); i++) {
				tagsNames += tags.get(i).name + "&&";
			}
		}
		JsonObject json = new JsonObject();
		json.addProperty("tagList", tagsNames);
		renderJSON(json.toString());
	}

	/**
	 * Returns a list of topics related to tag that a user can see
	 * 
	 * @param tag Tag
	 *            The tag that the user wants to browse
	 * @param user IdeaDeveloper
	 *            The Idea developer that performs the action
	 * @return A list of topics
	 */
	public static List viewTopicsTag(Tag tag, IdeaDeveloper user) {
		List<Topic> topics = tag.topics;
		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				if (!IdeaDeveloper.canViewTopic(user, topics.get(i))) {
					topics.remove(i);
				}
			}
		}
		return topics;
	}

	/**
	 * Returns a list of ideas related to tag that a user can see
	 * 
	 * @param tag Tag
	 *            The tag that the user wants to browse
	 * @param user IdeaDeveloper
	 *            The Idea developer that performs the action
	 * @return A list of topics
	 */
	public static List viewIdeasTag(Tag tag, IdeaDeveloper user) {
		List<Idea> ideas = tag.ideas;
		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				if (!user.canViewIdea(user, ideas.get(i))) {
					ideas.remove(i);
				}
			}
		}
		return ideas;
	}

	/**
	 * Renders a JSON object with string containig the ideas and topics related to
	 * a tag that can be viewed by a user
	 * 
	 * @author Sekkina
	 * @param tagName String,
	 * The name of the tag
	 * @param userName String,
	 * The username of the user applying the action
	 */
	public static void showTagContents(String tagName, String userName) {
		List temp = Tag.find("name=?", tagName).fetch();
		Tag tag = new Tag();
		if (temp != null && temp.size() > 0)
			tag = (Tag) temp.get(0);
		List temp2 = IdeaDeveloper.find("username=?", userName).fetch();
		IdeaDeveloper user = new IdeaDeveloper();
		if (temp2 != null && temp2.size() > 0)
			user = (IdeaDeveloper) temp2.get(0);
		List<Topic> topics = viewTopicsTag(tag, user);
		List<Idea> ideas = viewIdeasTag(tag, user);
		String topicsNames = "";
		String ideasNames = "";

		if (topics != null) {
			for (int i = 0; i < topics.size(); i++) {
				topicsNames += topics.get(i).id + "-" + topics.get(i).title
						+ "&&";
			}
		}

		if (ideas != null) {
			for (int i = 0; i < ideas.size(); i++) {
				ideasNames += ideas.get(i).id + "-" + ideas.get(i).title + "&&";
			}
		}

		JsonObject json = new JsonObject();
		json.addProperty("topics", topicsNames);
		json.addProperty("ideas", ideasNames);
		renderJSON(json.toString());
	}
	
	/**
	 * Renders a json object with the names of the tags starting with a ceratin letter
	 * @param startingLetter String,
	 * The letter the tags should be starting with
	 * @see 
	 * Renders a json onject with the names of tags to be viewed by the user on browsing all tags
	 */
	public static void browseTagsByCharacter(String startingLetter) {
		JsonObject renderedTags = new JsonObject();
		String renderedTagsNames = "";
		
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<Tag> tags = Tag.find("name like ? or name like ? order by name ASC",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();
		if (tags != null) {
			for (int i = 0; i < tags.size(); i++) {
					renderedTagsNames += tags.get(i).name + "&&";
			}
		}
		renderedTags.addProperty("tags", renderedTagsNames);
		renderJSON(renderedTags.toString());
	}

	// ----------------------------------------------------------------------------------------------------------------------------------------
	// ----------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * Renders the user name of the user logged in
	 * @see Loads the page BrowseAll.html
	 */
	public static void BrowseAll() {
		String user = Security.connected();
		render(user);
	}

	// -------------------------------------------------------Browse
	// members---------------------------------------------------------------------
	// ----------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * Renders a Json object with a string containing the usernames of members in an organization
	 * @param orgName String, 
	 * 				The name of the organization the user wants to check its members
	 * @see Renders a Json object with a string containing the usernames of members in an organization to be viewed in different 
	 * views by different ways
	 */
	public static void browseMembersInOrganization(String orgName) {
		Organization org = new Organization();
		JsonObject members = new JsonObject();
		String membersNames = "";
		try {
			org = Organization.find("name=?", orgName).first();
		} catch (Exception e) {
			members.addProperty("members", "-1");
			renderJSON(members.toString());
			return;
		}

		if (org.members != null) {
			for (int i = 0; i < org.members.size(); i++) {
				if (!org.blocked.contains(org.members.get(i)))
					membersNames += org.members.get(i).username + "&&";
			}
			members.addProperty("members", membersNames);
			renderJSON(members.toString());
		} else {
			members.addProperty("members", "-1");
			renderJSON(members.toString());
		}
	}
	
	/**
	 * Calls the method browseMembersInOrganization with the organization the idea belongs to
	 * @param ideaId long,
	 * The id of the idea
	 * @see Renders a Json object with a string containing the usernames of members in the organization where the idea belongs 
	 * to be viewed in different views by different ways
	 */
	public static void browseMembersInIdeaOrganization(long ideaId){
		browseMembersInOrganization(getIdeaOrganization(ideaId));
	}
	
	
	/**
	 * Calls the method browseMembersInOrganization with the organization the topic belongs to
	 * @param topicId long,
	 * The id of the topic
	 * @see Renders a Json object with a string containing the usernames of members in the organization where the topic belongs 
	 * to be viewed in different views by different ways
	 */
	public static void browseMembersInTopicOrganization(long topicId){
		browseMembersInOrganization(getTopicOrganization(topicId));
	}
	
	/**
	 * Calls the method browseMembersInOrganization with the organization the entity belongs to
	 * @param entityName String,
	 * The name of the entity
	 * @see Renders a Json object with a string containing the usernames of members in the organization where the entity belongs 
	 * to be viewed in different views by different ways
	 */
	public static void browseMembersInEntityOrganization(String entityName){
		browseMembersInOrganization(getEntityOrganization(entityName));
	}

	/**
	 * Calls the method browseMembersInOrganization with the organization the action plan belongs to
	 * @param actionPlanId long,
	 * The id of the action plan
	 * @see Renders a Json object with a string containing the usernames of members in the organization where the action plan belongs 
	 * to be viewed in different views by different ways
	 */
	public static void browseMembersInActionPlanOrganization(long actionPlanId){
		browseMembersInOrganization(getActionPlanOrganization(actionPlanId));
	}
	
	// -------------------------------------------------------Browsing Action plan-----------------------------------------------
	// ----------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 
	 * @param startingLetter
	 *            String, The letter that a user wants to see the action plans starting
	 *            with
	 * @param userName
	 *            String, The user name of the user currently logged in to the
	 *            system and browsing
	 * @see Renders a string with all the action plans that a user with username
	 *      userName and starting with the letter startingLetter to the page
	 *      BrowseAll.html
	 */
	public static void browseActionPlansByCharacter(String startingLetter,
			String userName) {
		JsonObject renderedActionPlans = new JsonObject();
		String renderedActionPlansNames = "";
		IdeaDeveloper user = new IdeaDeveloper();
		List temp = IdeaDeveloper.find("username = ?", userName).fetch();
		if (temp != null && temp.size() > 0)
			user = (IdeaDeveloper) temp.get(0);
		else {
			renderedActionPlans.addProperty("actionPlans", renderedActionPlansNames);
			renderJSON(renderedActionPlans.toString());
			return;
		}
		if (startingLetter != null && startingLetter.length() > 0) {
			startingLetter = startingLetter.substring(0, 1);
		} else {
			startingLetter = "a";
		}

		List<ActionPlan> actionPlans = ActionPlan.find(
				"name like ? or name like ? order by name ASC",
				startingLetter.toLowerCase() + "%",
				startingLetter.toUpperCase() + "%").fetch();
		if (actionPlans != null) {
			for (int i = 0; i < actionPlans.size(); i++) {
				if (IdeaDeveloper.canViewActionPlan(user, actionPlans.get(i))) {
					renderedActionPlansNames += actionPlans.get(i).id + "-" + actionPlans.get(i).name + "&&";
				}
			}
		}

		renderedActionPlans.addProperty("actionPlans", renderedActionPlansNames);
		renderJSON(renderedActionPlans.toString());
	}
	
	/**
	 * Gets back the name of the organization where an entity lies
	 * @param EntityName String, 
	 * The name of the entity
	 * @return String,
	 * The name of the organization where an entity lies
	 */
	public static String getEntityOrganization(String EntityName) {
		Entities entit = new Entities();
		try {
			entit = Entities.find("name=?", EntityName).first();
		} catch (Exception e) {
			return null;
		}

		if (entit.liesIn != null)
			return entit.liesIn.name;
		else
			return null;
	}
	
	
	/**
	 * Gets back the name of the organization where a topic lies
	 * @param topicId long, 
	 * The id of the topic
	 * @return String,
	 * The name of the organization where a topic lies
	 */
	public static String getTopicOrganization(long topicId) {
		Topic topic = new Topic();
		try {
			topic = Topic.findById(topicId);
		} catch (Exception e) {
			return null;
		}

		if (topic.topicOrg != null){
			return topic.topicOrg.name;
		}
			
		else if(topic.topicEnt != null) {
			return getEntityOrganization(topic.topicEnt.name);
		} else {
			return null;
		}
	}
	
	/**
	 * Gets back the name of the organization where a idea lies
	 * @param ideaId long, 
	 * The id of the idea
	 * @return String,
	 * The name of the organization where a idea lies
	 */
	public static String getIdeaOrganization(long ideaId){
		Idea idea = new Idea();
		try{
			idea = Idea.findById(ideaId);
		} catch(Exception e) {
			return null;
		}
		
		try{
			if(idea.ideaOrg != null){
				return idea.ideaOrg.name; 
			} else if(idea.ideaEnt != null){
				return getEntityOrganization(idea.ideaEnt.name);
			} else if(idea.ideaTopic != null) {
				return getTopicOrganization(idea.ideaTopic.id);
			} else {
				return null;
			}
		} catch(Exception e){
			return null;
		}
		
	}
	
	
	/**
	 * Gets back the name of the organization where an actionPlan lies
	 * @param actionPlanId long, 
	 * The id of the action plan
	 * @return String,
	 * The name of the organization where an action plan lies
	 */
	public static String getActionPlanOrganization(long actionPlanId){
		ActionPlan actionPlan = new ActionPlan();
		try{
			actionPlan = ActionPlan.findById(actionPlanId);
		} catch(Exception e){
			return null;
		}
		
		try{
				Organization org = Organization.findById(actionPlan.organizationId);
				return org.name;
		} catch(Exception e){
			return null;
		}
	}
	
	/**
	 * Gets the members in an organization sorted by community contribution
	 * @param orgId long,
	 * The id of the organization to get its members
	 * @see
	 * The members in an organiztion sorted by community contribution
	 */
	public static void browseMembersByCommunityCounter(long orgId){
		Organization org = new Organization();
		JsonObject members = new JsonObject();
		List<IdeaDeveloper> membersByCommunityCounter = new ArrayList<IdeaDeveloper>();
		String membersNames = "";
		try {
			org = Organization.findById(orgId);
			membersByCommunityCounter = Organization.find("select M from Organization O join O.members as M where O.id=?  order by M.communityCounter DESC", orgId).fetch(10);
		} catch (Exception e) {
			members.addProperty("members", "-1");
			renderJSON(members.toString());
			return;
		}

		if (membersByCommunityCounter != null) {
			for (int i = 0; i < membersByCommunityCounter.size(); i++) {
				if (!org.blocked.contains(membersByCommunityCounter.get(i)))
					membersNames += membersByCommunityCounter.get(i).id + "-" + membersByCommunityCounter.get(i).username + "-" + membersByCommunityCounter.get(i).communityCounter + "&&";
			}
			members.addProperty("members", membersNames);
			renderJSON(members.toString());
		} else {
			members.addProperty("members", "-1");
			renderJSON(members.toString());
		}
	}
}
